package org.example.springsecurity_.controller;


import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.example.springsecurity_.domain.MyUserDetails;
import org.example.springsecurity_.domain.ResponseResult;
import org.example.springsecurity_.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.security.Key;
import java.security.Principal;
import java.util.ArrayDeque;
import java.util.Date;
import java.util.HashMap;
import java.util.Objects;

@RestController
//@RequestMapping("/api")
public class UserController {
    @Autowired
    private BCryptPasswordEncoder passwordEncoder; // 注入密码编码器
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @RequestMapping("/api/login")
    public ResponseResult<String> login(@RequestBody User user){
        System.out.println("login");
        String username= user.getUsername();
        String password=user.getPassword();
//        principal(当前登录用户的用户名):主要的，当事人，主角
//        credentials(密码):凭证
//        用AuthenticationManager做用户登录的认证
        UsernamePasswordAuthenticationToken auth=new UsernamePasswordAuthenticationToken(username,password,new ArrayDeque<>(){});
        Authentication authenticate = null;

        try{
//            认证管理器的认证方法
            authenticate = authenticationManager.authenticate(auth);
        }catch (Exception e){
            e.printStackTrace();

            ResponseResult<String> stringResponseResult = new ResponseResult<>(-1,"用户名或密码错误",null);
            return stringResponseResult;
        }

        MyUserDetails principal=(MyUserDetails)authenticate.getPrincipal();
        System.out.println(principal);
        redisTemplate.opsForValue().set("login:"+user.getUsername(),user);


//        点击登录到jwt过滤器(因为没token),直接放到下个过滤器(自带的，不管)
//        来到目的地login接口，用认证管理器认证用户
//        下一步到service实现类的load..方法中 比对username | password是否正确
//        到DaoAuth类retriveUser方法(各种方法)
//        新的登录请求/userinfo.html页面


        //令牌-JWT生成令牌
        Key key= Keys.secretKeyFor(SignatureAlgorithm.HS256);
        HashMap<String, Object> map=new HashMap<>();
        map.put("username","abc");

        JwtBuilder jwtBuilder = Jwts.builder()
                .setClaims(map)//声明
                .setIssuedAt(new Date())//颁发时间
                .setSubject(username)
                .signWith(key);//签名的key
        String token=jwtBuilder.compact();//JWT
        System.out.println("token_:"+token);

        ResponseResult<String> stringResponseResult = new ResponseResult<>(1,"登陆成功",null);
        return stringResponseResult;
    }

    @ResponseBody
    @RequestMapping("/userinfo/{userid}")
    // 是否有某某权限
    @PreAuthorize("hasAnyAuthority('sbszt')")
    public ResponseResult<String> getUserInfo(@PathVariable("userid") String userid){
        System.out.println(userid);
        ResponseResult<String> stringResponseResult = new ResponseResult<>(1,"登陆成功","sbszt");
        return stringResponseResult;
    }

    @RequestMapping("/logout")
    public String logout(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 检查Principal是否为UserDetails类型
        if (authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            String username = userDetails.getUsername(); // 获取用户名
            String loginKey = "login:" + username;
            redisTemplate.delete(loginKey);
            return "退出成功";
        } else {
            return "退出失败";
        }
    }
}
